package com.example.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.domain.User;
import com.example.dto.AdminAddDTO;
import com.example.dto.UserLoginDTO;
import com.example.dto.UserRegisterDTO;
import com.example.dto.UserUpdateDTO;
import com.example.exception.BusinessException;
import com.example.mapper.UserMapper;
import com.example.security.LoginUser;
import com.example.service.OperationLogService;
import com.example.service.UserService;
import com.example.util.JwtUtil;
import com.example.util.Result;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
* @author HP
* @description 针对表【user】的数据库操作Service实现
* @createDate 2025-08-18 19:33:25
*/

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Resource
    private UserMapper userMapper;

    @Resource
    private OperationLogService operationLogService;

    @Autowired
    AuthenticationManager authenticationManager;

    @Override
    public Result register(UserRegisterDTO userRegisterDTO) {
        // 检查用户名是否已存在
        QueryWrapper<User> isUsernameExist = new QueryWrapper<>();
        isUsernameExist.eq("username", userRegisterDTO.getUsername());
        User usernameUser = userMapper.selectOne(isUsernameExist);
        if (usernameUser != null) {
            throw new BusinessException("该用户名已被注册");
        }
        // 加密密码
        String hashedPassword = passwordEncoder.encode(userRegisterDTO.getPassword());
        userRegisterDTO.setPassword(hashedPassword);
        User user = new User();
        user.setUsername(userRegisterDTO.getUsername());
        user.setPassword(hashedPassword);

        int insert = userMapper.insert(user);
        if (insert <= 0) {
            throw new BusinessException("注册失败");
        }
        return Result.success();
    }

    @Override
    public Result login(UserLoginDTO userLoginDTO) {

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(userLoginDTO.getUsername(),userLoginDTO.getPassword());

        //AuthenticationManager authentication进行用户认证
        Authentication authentication = authenticationManager.authenticate(authenticationToken);

        log.info("用户认证成功，用户信息：{}", authentication.getPrincipal());

        String token = JwtUtil.createToken((LoginUser) authentication.getPrincipal());
        return Result.success(Map.of("token", token));
    }

    @Override
    public Result updateUserInfo(UserUpdateDTO userUpdateDTO) {

        // 检查用户是否存在
        User existingUser = userMapper.selectById(userUpdateDTO.getId());
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }

        // 如果修改了邮箱，检查是否已存在
        if (userUpdateDTO.getEmail() != null && !userUpdateDTO.getEmail().equals(existingUser.getEmail())) {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("email", userUpdateDTO.getEmail());
            queryWrapper.ne("id", userUpdateDTO.getId());
            User emailUser = userMapper.selectOne(queryWrapper);
            if (emailUser != null) {
                throw new BusinessException("该邮箱已被注册");
            }
        }

        // 更新用户信息
        User updateUser = new User();

        BeanUtils.copyProperties(userUpdateDTO, updateUser);

        int update = userMapper.updateById(updateUser);
        if (update <= 0) {
            throw new BusinessException("更新用户信息失败");
        }
        return Result.success();
    }

    @Override
    public Result changePassword(Long userId, String oldPassword, String newPassword) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }
        if (oldPassword == null || oldPassword.trim().isEmpty()) {
            throw new BusinessException("旧密码不能为空");
        }
        if (newPassword == null || newPassword.trim().isEmpty()) {
            throw new BusinessException("新密码不能为空");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())){
            throw new BusinessException("旧密码错误");
        }

        // 加密新密码
        String hashedPassword = passwordEncoder.encode(newPassword);
        user.setPassword(hashedPassword);

        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("修改密码失败");
        }
        return Result.success();
    }

    @Override
    public User getUserByUsername(String username) {
        if (username == null || username.trim().isEmpty()) {
            throw new BusinessException("用户名不能为空");
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        return user;
    }

    @Override
    public Result getUserById(Long id) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        return Result.success(Map.of("user", user));
    }

    @Override
    public Result disableBorrow(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setBorrowDisabled(1);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("禁用借书失败");
        }
        return Result.success();
    }

    @Override
    public Result enableBorrow(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setBorrowDisabled(0);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("启用借书失败");
        }
        return Result.success();
    }

    @Override
    public Result disableReservation(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setBorrowDisabled(1);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("禁用预约失败");
        }
        return Result.success();
    }

    @Override
    public Result enableReservation(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setBorrowDisabled(0);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("启用预约失败");
        }
        return Result.success();
    }

    @Override
    public Result disableEntry(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setEntryDisabled(1);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("禁用入馆失败");
        }
        return Result.success();
    }

    @Override
    public Result enableEntry(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setEntryDisabled(0);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("启用入馆失败");
        }
        return Result.success();
    }


    @Override
    public Result logout() {
        SecurityContextHolder.clearContext();
        return Result.success();
    }

    @Override
    public Result addAdmin(AdminAddDTO adminAddDTO) {
        // 检查用户名是否已存在
        if(userMapper.selectOne(new QueryWrapper<User>().eq("username", adminAddDTO.getUsername())) != null){
            throw new BusinessException("该用户名已被注册");
        }
        // 加密密码 (默认密码123456)
        String hashedPassword = passwordEncoder.encode("123456");
        User admin = new User();
        BeanUtils.copyProperties(adminAddDTO, admin);
        admin.setRole(2);
        admin.setPassword(hashedPassword);
        int insert = userMapper.insert(admin);
        if (insert <= 0) {
            throw new BusinessException("添加管理员失败");
        }
        return Result.success();
    }

    @Override
    public Result deleteAdmin(Long id) {
        // 检查用户是否存在
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        // 检查是否是管理员用户
        if (user.getRole() != 2) {
            throw new BusinessException("不是管理员用户，不能删除");
        }
        int delete = userMapper.deleteById(id);
        if (delete <= 0) {
            throw new BusinessException("删除管理员失败");
        }
        return Result.success();
    }

    @Override
    public Result getUsers() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", 3);
        List<User> users = userMapper.selectList(queryWrapper);
        return Result.success(Map.of("users", users));
    }

    @Override
    public Result getAdmins() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role", 2);
        List<User> admins = userMapper.selectList(queryWrapper);
        return Result.success(Map.of("admins", admins));
    }

    @Override
    public Result resetPassword(Long userId) {
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        // 加密密码 (默认密码123456)
        String hashedPassword = passwordEncoder.encode("123456");
        user.setPassword(hashedPassword);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("重置密码失败");
        }
        return Result.success();
    }

    @Override
    public Result changeAdminStatus(Long userId, Integer status) {
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        // 检查是否是管理员用户
        if (user.getRole() != 2) {
            throw new BusinessException("不是管理员用户，不能修改状态");
        }
        // 根据status参数设置管理员状态：1启用，0禁用
        user.setStatus(status);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("操作失败");
        }
        return Result.success();
    }

    @Override
    public Result changeUserStatus(Long userId, Integer status) {
        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        // 检查是否是用户
        if (user.getRole() != 3) {
            throw new BusinessException("不是用户，不能修改状态");
        }
        // 根据status参数设置用户状态：1启用，0禁用
        user.setStatus(status);
        int update = userMapper.updateById(user);
        if (update <= 0) {
            throw new BusinessException("操作失败");
        }
        return Result.success();
    }

    @Override
    public Result getUserById() {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (loginUser == null){
            throw new BusinessException("用户未登录");
        }
        User user = userMapper.selectById(loginUser.getId());
        if (user == null){
            throw new BusinessException("用户不存在");
        }
        return Result.success(Map.of("user", user));
    }
}




